#include "./../inc/main.h"

/* 网络模块 */

int sockfd = -1;                                         // 全局套接字描述符
pthread_t recv_thread;                                   // 接收线程ID
int is_connected = 0;                                    // 连接状态标志
pthread_mutex_t match_mutex = PTHREAD_MUTEX_INITIALIZER; // 初始化互斥锁
MatchState match_state = MATCH_NONE;                     // 当前匹配状态
MoveData opponentMove;
bool hasOpponentMove = false;

// 发送匹配请求
void send_match_request()
{
    if (!is_connected)
        return;
    const char *msg = "MATCH_REQUEST";
    send(sockfd, msg, strlen(msg), 0);
    match_state = MATCH_SEARCHING;
    cout<<"正在匹配..."<<endl;
}

// 发送取消匹配请求
void send_cancel_match()
{
    if (match_state != MATCH_SEARCHING)
        return;
    const char *msg = "MATCH_CANCEL";
    send(sockfd, msg, strlen(msg), 0);
    // 加锁修改匹配状态
    pthread_mutex_lock(&match_mutex);
    match_state = MATCH_NONE;
    pthread_mutex_unlock(&match_mutex);
}

// 获取当前匹配状态
MatchState get_match_state()
{
    pthread_mutex_lock(&match_mutex);
    MatchState state = match_state;
    pthread_mutex_unlock(&match_mutex);
    return state;
}

// 重置匹配状态（断开连接时用）
void reset_match_state()
{
    pthread_mutex_lock(&match_mutex);
    match_state = MATCH_NONE;
    pthread_mutex_unlock(&match_mutex);
}

// 发送移动数据到服务器
void send_move_data(int fromX, int fromY, int toX, int toY, PieceType type, PieceColor color)
{
    if (!is_connected)
        return;

    // 创建消息包
    char buffer[BUFFER_SIZE];
    memset(buffer, 0, BUFFER_SIZE);

    // 设置消息类型
    int msgType = MSG_MOVE_DATA;
    memcpy(buffer, &msgType, sizeof(int));

    // 设置移动数据
    MoveData moveData;
    moveData.fromX = fromX;
    moveData.fromY = fromY;
    moveData.toX = toX;
    moveData.toY = toY;
    moveData.pieceType = type;
    moveData.pieceColor = color;
    memcpy(buffer + sizeof(int), &moveData, sizeof(MoveData));
    send(sockfd, buffer, sizeof(int) + sizeof(MoveData), 0);
    cout << "发送移动数据:从(" << fromX << "," << fromY << ")到(" << toX << "," << toY << ")" << " 棋子类型为:" << type << " 棋子颜色为:" << color << endl;
}

void handle_opponent_move(int fromX, int fromY, int toX, int toY, PieceType type, PieceColor color)
{
    // 存储对手移动数据
    opponentMove.fromX = fromX;
    opponentMove.fromY = fromY;
    opponentMove.toX = toX;
    opponentMove.toY = toY;
    opponentMove.pieceType = type;
    opponentMove.pieceColor = color;
    hasOpponentMove = true;
    cout << "收到对方移动数据:从(" << fromX << "," << fromY << ")到(" << toX << "," << toY << ")" << " 棋子类型为:" << type << " 棋子颜色为:" << color << endl;
}

// 扩展接收线程处理匹配消息
void *recv_from_server(void *arg)
{
    char buffer[BUFFER_SIZE];
    while (is_connected)
    {
        memset(buffer, 0, BUFFER_SIZE);
        int len = recv(sockfd, buffer, BUFFER_SIZE - 1, 0);

        // 处理接收结果
        if (len <= 0)
        {
            if (errno != EAGAIN && errno != EWOULDBLOCK)
            {
                perror("接收失败或连接断开");
                disconnect_from_server();
                reset_match_state();
                break;
            }
            continue;
        }

        // 解析消息类型
        int msgType;
        memcpy(&msgType, buffer, sizeof(int));

        switch (msgType)
        {
        case MSG_MATCH_FOUND:
        {
            cout<<"匹配成功！进入游戏..."<<endl;
            pthread_mutex_lock(&match_mutex); // 加锁
            match_state = MATCH_SUCCESS;
            pthread_mutex_unlock(&match_mutex); // 解锁
            break;
        }
        case MSG_MATCH_TIMEOUT:
        {
            cout<<"匹配超时，请重试"<<endl;
            pthread_mutex_lock(&match_mutex); // 加锁
            match_state = MATCH_NONE;
            pthread_mutex_unlock(&match_mutex); // 解锁
            break;
        }
        case MSG_MOVE_DATA:
        {
            // 处理对手的走棋数据
            MoveData moveData;
            memcpy(&moveData, buffer + sizeof(int), sizeof(MoveData));
            handle_opponent_move(
                moveData.fromX, moveData.fromY,
                moveData.toX, moveData.toY,
                moveData.pieceType, moveData.pieceColor);
            break;
        }
        default:
        {
            // 兼容旧版本的消息格式
            if (strcmp(buffer, "MATCH_FOUND") == 0)
            {
                cout<<"匹配成功！进入游戏..."<<endl;
                pthread_mutex_lock(&match_mutex); // 加锁
                match_state = MATCH_SUCCESS;
                pthread_mutex_unlock(&match_mutex); // 解锁
            }
            else if (strcmp(buffer, "MATCH_TIMEOUT") == 0)
            {
                cout<<"匹配超时，请重试"<<endl;
                pthread_mutex_lock(&match_mutex); // 加锁
                match_state = MATCH_NONE;
                pthread_mutex_unlock(&match_mutex); // 解锁
            }
            break;
        }
        }
    }
    return NULL;
}

// 连接到服务器
int connect_to_server(void)
{
    if (is_connected)
        return 0;

    // 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        perror("socket creation failed");
        return -1;
    }

    // 设置接收超时
    struct timeval timeout;
    timeout.tv_sec = 1;
    timeout.tv_usec = 0;
    if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) < 0)
    {
        perror("设置接收超时失败");
        close(sockfd);
        sockfd = -1;
        return -1;
    }

    // 设置服务器地址
    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);

    // 转换IP地址
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0)
    {
        perror("转换IP地址失败");
        close(sockfd);
        sockfd = -1;
        return -1;
    }

    // 连接服务器
    if (connect(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        perror("连接服务器失败");
        close(sockfd);
        sockfd = -1;
        return -1;
    }

    is_connected = 1;

    // 创建接收线程
    if (pthread_create(&recv_thread, NULL, recv_from_server, NULL) != 0)
    {
        perror("创建线程失败");
        close(sockfd);
        sockfd = -1;
        is_connected = 0;
        return -1;
    }
    cout << "已连接到服务器" << endl;
    return 0;
}

// 断开与服务器的连接
void disconnect_from_server(void)
{
    if (!is_connected)
        return;
    is_connected = 0;
    close(sockfd);
    sockfd = -1;

    // 等待接收线程退出
    if (pthread_join(recv_thread, NULL) != 0)
    {
        perror("等待线程退出失败");
    }

    cout<<"已断开与服务器的连接"<<endl;
}